home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctj8504.arc / CRC.C < prev    next >
Text File  |  1986-09-14  |  4KB  |  159 lines

  1.  
  2. /*------------------------------------------------------*/
  3. /*     High Performance CRC Computation Routine    */
  4. /*                            */
  5. /*      Copyright 1985 W. David Schwaderer        */
  6. /*           All rights reserved            */
  7. /*                            */
  8. /*    Compiler used: Computer Innovations C86 V2.10A    */
  9. /*                            */
  10. /*     Warning...this program uses bit fields!    */
  11. /*      For warnings on bit field hazards see:    */
  12. /*                            */
  13. /*    The C Wizard's Programming Reference Handbook     */
  14. /*         W. David Schwaderer            */
  15. /*          John Wiley and Sons, 1985         */
  16. /*                            */
  17. /*------------------------------------------------------*/
  18.  
  19. watch bit fields...see my C book... */
  20.  
  21. #include "stdio.h"
  22.  
  23. #define VOID int
  24.  
  25. unsigned crc_table[256];     /*   globally accessible  */
  26.  
  27.  
  28. main(argc, argv)
  29. int   argc;
  30. char *argv[];
  31. {
  32.   VOID       GenerateTable();
  33.   unsigned GenerateCRC();
  34.  
  35.   unsigned length, crc;
  36.  
  37.                 /* crc = 0x9001 */
  38.   static char TestArray1[] = {'\001', '\000'};
  39.  
  40.   static char TestArray2[] = {'\001','\000', '\001', '\220'};
  41.                  /* bytewise      bytewise */
  42.                  /* unreversed    reversed */
  43.  
  44.   static char TestMsg[] = "This is a test message.";
  45.  
  46.   GenerateTable();        /* fill in the crc_table  */
  47.  
  48.   PrintTable();         /* display the table      */
  49.  
  50.   length = sizeof(TestArray1);
  51.   crc = GenerateCRC(length, TestArray1); /* calculate CRC */
  52.   printf("\n\n\nTestArray1 CRC = 0x%04x", crc);
  53.  
  54.   length = sizeof(TestArray2);
  55.   crc = GenerateCRC(length, TestArray2); /* calculate CRC */
  56.   printf("\n\n\nTestArray2 CRC = 0x%04x", crc);
  57.  
  58.   length = sizeof(TestMsg) - 1; /* avoid terminating NUL  */
  59.   crc = GenerateCRC(length, TestMsg); /* calculate a CRC  */
  60.   printf("\n\n\nText = [%s]\nCRC = %04x\n\n", TestMsg, crc);
  61.  
  62.   return(0);
  63.  
  64. }
  65.  
  66. VOID GenerateTable()   /* generate the look-up table */
  67. {
  68.   int temp;
  69.   union { int i;
  70.       struct {
  71.              unsigned i1  :1;  /* low order bit  */
  72.              unsigned i2  :1;
  73.              unsigned i3  :1;
  74.              unsigned i4  :1;
  75.              unsigned i5  :1;
  76.              unsigned i6  :1;
  77.              unsigned i7  :1;
  78.              unsigned i8  :1;  /* high order bit */
  79.              unsigned      :8;  /* unused     */
  80.       } Bit;
  81.     } iUn;
  82.  
  83.   union {  unsigned int  Entry;
  84.        struct {
  85.              unsigned b1  :1;  /* low order bit  */
  86.              unsigned b2  :1;
  87.              unsigned b3  :1;
  88.              unsigned b4  :1;
  89.              unsigned b5  :1;
  90.              unsigned b6  :1;
  91.              unsigned b7  :1;
  92.              unsigned b8  :1;
  93.              unsigned b9  :1;
  94.              unsigned b10 :1;
  95.              unsigned b11 :1;
  96.              unsigned b12 :1;
  97.              unsigned b13 :1;
  98.              unsigned b14 :1;
  99.              unsigned b15 :1;
  100.              unsigned b16 :1;  /* high order bit */
  101.           } EntryBit;
  102.     } EntryUn;
  103.  
  104.   for (iUn.i = 0; iUn.i < 256; iUn.i++) {
  105.  
  106.     EntryUn.Entry = 0; /* bits 2 thru 6 zeroed out now */
  107.  
  108.     temp = (iUn.Bit.i7 ^ iUn.Bit.i6 ^ iUn.Bit.i5 ^
  109.         iUn.Bit.i4 ^ iUn.Bit.i3 ^ iUn.Bit.i2 ^
  110.         iUn.Bit.i1);
  111.  
  112.     EntryUn.EntryBit.b16 = (iUn.Bit.i8 ^ temp);
  113.     EntryUn.EntryBit.b15 = (temp);
  114.     EntryUn.EntryBit.b14 = (iUn.Bit.i8 ^ iUn.Bit.i7);
  115.     EntryUn.EntryBit.b13 = (iUn.Bit.i7 ^ iUn.Bit.i6);
  116.     EntryUn.EntryBit.b12 = (iUn.Bit.i6 ^ iUn.Bit.i5);
  117.     EntryUn.EntryBit.b11 = (iUn.Bit.i5 ^ iUn.Bit.i4);
  118.     EntryUn.EntryBit.b10 = (iUn.Bit.i4 ^ iUn.Bit.i3);
  119.     EntryUn.EntryBit.b9  = (iUn.Bit.i3 ^ iUn.Bit.i2);
  120.     EntryUn.EntryBit.b8  = (iUn.Bit.i2 ^ iUn.Bit.i1);
  121.     EntryUn.EntryBit.b7  = (iUn.Bit.i1);
  122.     EntryUn.EntryBit.b1  = (iUn.Bit.i8 ^ temp);
  123.  
  124.     crc_table[iUn.i] = EntryUn.Entry;
  125.  
  126.   }
  127.  
  128. }
  129.  
  130. VOID PrintTable()     /* print out the look-up table */
  131. {
  132.   int i;
  133.  
  134.   for (i = 0; i < 256; i++) {
  135.      if ( !(i % 8) )
  136.        printf("\n %02x  -  %04x", i, crc_table[i]);
  137.      else
  138.        printf("  %04x", crc_table[i]);
  139.   }
  140. }
  141.  
  142. unsigned GenerateCRC(Length, TextPtr)
  143.   unsigned  Length;
  144.   char       *TextPtr;
  145. {
  146.   int i, index;
  147.   unsigned crc;
  148.  
  149.   crc = 0;    /* crc starts at zero for each message */
  150.  
  151.   for (i = 0; i < Length; i++, TextPtr++) {
  152.     index = ( (crc ^ *TextPtr) & 0x00FF);
  153.     crc = ( (crc >> 8) & 0x00FF) ^ crc_table[index];
  154.   }
  155.  
  156.   return(crc);
  157.  
  158. }
  159.